package fileUtils

import (
	"crypto/sha1"
	"encoding/hex"
	"fmt"
	"gitee.com/houlisus/jiaolong/commonUtils"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"
)

/**
 * @Author $
 * @Description //TODO $
 * @Date $ $
 * @Param $
 * @return $
 **/
func GetCurrentDirectory() string {
	//返回绝对路径  filepath.Dir(os.Args[0])去除最后一个元素的路径
	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
	}
	//将\替换成/
	return strings.Replace(dir, "\\", "/", -1)
}

/*
判断文件十分存在
*/
func Exist(filename string) bool {
	_, err := os.Stat(filename)
	return err == nil || os.IsExist(err)
}

//IsDir
// 判断所给路径是否为文件夹
//
func IsDir(path string) bool {
	s, err := os.Stat(path)
	if err != nil {
		return false
	}
	return s.IsDir()
}

//IsFile
// 判断所给路径是否为文件
//
func IsFile(path string) bool {
	return !IsDir(path)
}

func Hash_file_sha1(filePath string) (string, error) {
	//Initialize variable returnMD5String now in case an error has to be returned
	var returnSHA1String string

	//Open the filepath passed by the argument and check for any error
	file, err := os.Open(filePath)
	if err != nil {
		return returnSHA1String, err
	}

	//Tell the program to call the following function when the current function returns
	defer file.Close()

	//Open a new SHA1 hash interface to write to
	hash := sha1.New()

	//Copy the file in the hash interface and check for any error
	if _, err := io.Copy(hash, file); err != nil {
		return returnSHA1String, err
	}
	//Get the 20 bytes hash
	hashInBytes := hash.Sum(nil)[:20]

	//Convert the bytes to a string
	returnSHA1String = hex.EncodeToString(hashInBytes)

	return returnSHA1String, nil

}

func GetListFiles(path string) []string {
	var results []string
	files, _ := ioutil.ReadDir(path)
	for _, f := range files {
		results = append(results, filepath.Join(path, f.Name()))
	}
	return results
}

// GetFilenameWithSuffix
//获取文件名带后缀
//fullFilename 完整文件名称带路径,/var/data/test.txt
//返回值 test.txt
//
func GetFilenameWithSuffix(fullFilename string) string {
	if commonUtils.IsWindows() {
		fullFilename = filepath.ToSlash(fullFilename)
	}
	return path.Base(fullFilename)
}

//GetFileSuffix
//获取文件后缀
//
func GetFileSuffix(filenameWithSuffix string) string {
	if commonUtils.IsWindows() {
		filenameWithSuffix = filepath.ToSlash(filenameWithSuffix)
	}
	return path.Ext(filenameWithSuffix)
}

//GetFileNameNotSuffix
//获取文件名
//
func GetFileNameNotSuffix(fullFilename string) string {
	filenameWithSuffix := GetFilenameWithSuffix(fullFilename)
	fileSuffix := GetFileSuffix(filenameWithSuffix)
	return strings.TrimSuffix(filenameWithSuffix, fileSuffix) //获取文件名
}

//GetFullNameNotSuffix
//获取不带后缀的完整文件名称
//
func GetFullNameNotSuffix(fullFilename string) string {
	if commonUtils.IsWindows() {
		fullFilename = filepath.ToSlash(fullFilename)
	}
	paths, _ := filepath.Split(fullFilename)
	fileNotSuffix := GetFileNameNotSuffix(fullFilename)
	return filepath.Join(paths, fileNotSuffix)
}

//GetBasePath
//获取基础路径
//
func GetBasePath(fullFilename string) string {
	if commonUtils.IsWindows() {
		fullFilename = filepath.ToSlash(fullFilename)
	}
	paths, _ := filepath.Split(fullFilename)
	return paths
}

//ReplaceSuffix
//替换完整文件后缀
//
func ReplaceSuffix(fullFilename string, newSuffix string) string {
	return GetFullNameNotSuffix(fullFilename) + newSuffix
}

func FindAllFileBySuffix(basePath string, suffix string) []string {
	if commonUtils.IsWindows() {
		basePath = filepath.ToSlash(basePath)
	}
	var allFiles []string
	finfo, _ := ioutil.ReadDir(basePath)
	for _, x := range finfo {
		realPath := filepath.Join(basePath, x.Name())
		//fmt.Println(x.Name()," ",x.Size())
		if x.IsDir() {
			allFiles = append(allFiles, FindAllFileBySuffix(realPath, suffix)...)
		} else {
			if strings.HasSuffix(realPath, suffix) {
				allFiles = append(allFiles, realPath)
			}
		}
	}
	return allFiles
}

func CopyFile(dstName, srcName string) (written int64, err error) {
	src, err := os.Open(srcName)
	if err != nil {
		return
	}
	defer src.Close()
	dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		return
	}
	defer dst.Close()
	return io.Copy(dst, src)
}

func CopyFileByBuffer(src, dst string, bufferSize int64) error {
	sourceFileStat, err := os.Stat(src)
	if err != nil {
		return err
	}

	if !sourceFileStat.Mode().IsRegular() {
		return fmt.Errorf("%s is not a regular file.", src)
	}

	source, err := os.Open(src)
	if err != nil {
		return err
	}
	defer source.Close()

	_, err = os.Stat(dst)
	if err == nil {
		return fmt.Errorf("File %s already exists.", dst)
	}

	destination, err := os.Create(dst)
	if err != nil {
		return err
	}
	defer destination.Close()

	if err != nil {
		panic(err)
	}

	buf := make([]byte, bufferSize)
	for {
		n, err := source.Read(buf)
		if err != nil && err != io.EOF {
			return err
		}
		if n == 0 {
			break
		}
		if _, err := destination.Write(buf[:n]); err != nil {
			return err
		}
	}
	return err
}
